package com.stardata.liangshisq.tcslmon.util;

import com.fasterxml.jackson.databind.JsonNode;
import org.apache.log4j.Logger;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.List;


/**
 * 基础控制类
 * @author harmon
 * @date 2016年9月2日
 */
public class ApiBaseAction {
    protected Logger logger = Logger.getLogger(getClass());

    /**
     * 得到request对象
     */
    @Autowired
    protected HttpServletRequest request;

    /**
     * 参数绑定异常
     */
    @ExceptionHandler({BindException.class, MissingServletRequestParameterException.class, UnauthorizedException.class, TypeMismatchException.class})
    @ResponseBody
    public R bindException(Exception e) {
        logger.error("bindException===>", e);

        if (e instanceof BindException) {
            return response(HttpStatus.BAD_REQUEST, 1, "参数绑定异常", e.getMessage());
        } else if (e instanceof UnauthorizedException) {
            return response(HttpStatus.FORBIDDEN,1, "无访问权限", e.getMessage());
        }
        return response(HttpStatus.INTERNAL_SERVER_ERROR, 1, "处理异常", e.getMessage());
    }

    /**
     * @param requestCode 返回码
     * @param msg 返回消息
     * @param data 返回数据
     * @return R
     * @Description: 构建统一格式返回对象
     * @date 2016年9月2日
     * @author zhuliyun
     */
    public R response(HttpStatus status, int requestCode, String msg, Object data) {
        R r = R.custom(status, msg);
        r.put("errcode", requestCode);
        r.put("errmsg", msg);
        if (data != null)
            r.put("data", data);
        return r;
    }

    public R success() {
        return response(HttpStatus.OK,0, "执行成功", null);
    }

    public R success(Object data) {
        R rp = response(HttpStatus.OK,0, "执行成功", data);
        logger.info("response:" + rp);
        return rp;
    }

    public R success(String key, Object data) {
        R rp = response(HttpStatus.OK,0, "执行成功", null);
        rp.put(key, data);
        logger.info("response:" + rp);
        return rp;
    }

    public R successList(List<?> list) {
        R result = response(HttpStatus.OK,0, "执行成功", null);
        return result.put("list", list);
    }

    public R success(HttpStatus status) {
        return response(status,0, "执行成功", null);
    }

    public R success(HttpStatus status, Object data) {
        R rp = response(status,0, "执行成功", data);
        logger.info("response:" + rp);
        return rp;
    }

    public R success(HttpStatus status, String key, Object data) {
        R rp = response(status,0, "执行成功", null);
        rp.put(key, data);
        logger.info("response:" + rp);
        return rp;
    }

    public R fail(HttpStatus status, String msg) {
        return R.custom(status, msg);
    }


    /**
     * initBinder 初始化绑定 <br>
     * 这里处理了3种类型<br>
     * 1、字符串自动 trim 去掉前后空格 <br>
     * 2、java.util.Date 转换为 "yyyy-MM-dd HH:mm:ss" 格式<br>
     * 3、java.sql.Date 转换为 "yyyy-MM-dd" 格式<br>
     * 4、java.util.Timestamps 时间转换
     *
     * @param binder  WebDataBinder 要注册的binder
     * @param request 前端请求
     */
    @InitBinder
    public void initBinder(WebDataBinder binder, WebRequest request) {

        // 字符串自动Trim
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));
    }

    /**
     * 获取请求方IP
     *
     * @return 客户端Ip
     */
    public String getClientIp() {
        String xff = request.getHeader("X-Real-IP");
        if(xff!=null) {
            return xff;
        }
        xff = request.getHeader("x-forwarded-for");
        if (xff == null) {
            return "8.8.8.8";
        }
        return xff;
    }

    public JsonNode getJsonRequest() {
        JsonNode result = null;
        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = request.getReader()) {
            char[] buff = new char[2048];
            int len;
            while ((len = reader.read(buff)) != -1) {
                sb.append(buff, 0, len);
            }
            result = JSONUtil.readTree(sb.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    public String getStringRequest() {
        String result = null;
        StringBuilder sb = new StringBuilder();
        try (BufferedReader reader = request.getReader()) {
            char[] buff = new char[2048];
            int len;
            while ((len = reader.read(buff)) != -1) {
                sb.append(buff, 0, len);
            }
            result = sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

}
